package com.cloudptt.api.product;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import com.cloudptt.api.comm.CheckData;
import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.models.lbs.LocationData;
import com.cloudptt.api.models.lbs.ReportData;
import com.cloudptt.api.product.adapter.GCallEventAdapter;
import com.cloudptt.api.product.adapter.PCallEventAdapter;
import com.cloudptt.api.product.battery.BatteryBroadcast;
import com.cloudptt.api.product.battery.Batteryistener;
import com.cloudptt.api.product.config.lbs.LocationConfig;
import com.cloudptt.api.product.func.IFunc;
import com.cloudptt.api.product.func.SipOperator;
import com.cloudptt.api.product.func.addr.AddrFunc;
import com.cloudptt.api.product.func.addr.AddrListener;
import com.cloudptt.api.product.func.addr.IAddrDefaultOp;
import com.cloudptt.api.product.func.addr.IAddrOp;
import com.cloudptt.api.product.func.call.CallFunc;
import com.cloudptt.api.product.func.call.CallListener;
import com.cloudptt.api.product.func.call.CallTimer;
import com.cloudptt.api.product.func.call.group.GroupCallSpeakListener;
import com.cloudptt.api.product.func.lbs.LBSFunc;
import com.cloudptt.api.product.func.media.EventListener;
import com.cloudptt.api.product.func.media.MediaFunc;
import com.cloudptt.api.product.func.message.AppLogListener;
import com.cloudptt.api.product.func.message.MsgFunc;
import com.cloudptt.api.product.func.message.MsgListener;
import com.cloudptt.api.product.func.message.NotifyListener;
import com.cloudptt.api.product.func.message.NotifyNewGroupListener;
import com.cloudptt.api.product.func.sys.IRestartServer;
import com.cloudptt.api.product.func.sys.SysFunc;
import com.cloudptt.api.product.func.sys.SysStateInfo;
import com.cloudptt.api.product.func.sys.listener.SysListener;
import com.cloudptt.api.product.func.sys.listener.SysMsgListener;
import com.cloudptt.api.product.func.voice.VoiceReportFunc;
import com.cloudptt.api.product.log.CrashHandler;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.operator.SysOperator;
import com.cloudptt.api.product.res.Resource;
import com.cloudptt.api.product.update.UpdateListener;
import com.cloudptt.api.product.update.UpdateManager;
import com.cloudptt.api.product.upload.UploadListener;
import com.cloudptt.api.product.upload.UploadManager;
import com.mcptt.config.ConfigCenter;
import com.mcptt.config.DbOperatorManager;
import com.mcptt.config.local.SysConfig;
import com.mcptt.config.model.McIdInfo;
import com.mcptt.config.model.McpttLoginInfo;
import com.mcptt.config.model.ServerInfo;
import com.mcptt.db.model.AddrInfo;
import com.mcptt.db.model.GroupInfo;
import com.mcptt.db.model.UserInfo;
import com.tencent.bugly.crashreport.CrashReport;
//import com.cloudptt.api.product.config.sys.SysConfig;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.PowerManager;
import android.os.SystemClock;


public class Product implements SysListener,
		IRestartServer,ILanChange,NetworkListener,Batteryistener,
		IFunc,IAddrDefaultOp,IAddrOp,UpdateListener,IGetReportData
{
	public static String Log_Key = "Product";
	private final static String TENCENT_BUGLY_APPID = "900021303";
	private static int ProductType = ProductConst.ProductType_PAPP;
	private Context ctx = null;
	//	private static int terminalType = 3;
	private ConfigCenter configCenter = null;
	private SysConfig sysConfig = null;
	private boolean isLogined = false;

	private ProductOperator operator = null;
	private DbOperatorManager dbManager = null;
	private NetWorkBroadcast netBroadcast = null;
	private BatteryBroadcast batteryBroadcast = null;
	private ReportAndKeepLive reportAndKeepLive = null;

	private NetworkListener networkListener = null;
	private Batteryistener batteryistener = null;

	private UpdateListener updateListener = null;

	//	private LoginListener loginListener = null;
	private SysListener sysListener = null;
//	private GroupCallSpeakListener groupCallSpeakListener = null;
//	private SysAddrListener sysAddrListener = null;



	private ISetDefaultGroup defaultGroupListener = null;

	private IFunc funArr[] = new IFunc[ProductConst.Func_Count];

	private GCallEventAdapter gCallEventAdapter = null;
	private PCallEventAdapter pCallEventAdapter = null;

	private AddrInfo curGroupInfo = null;
	private AddrInfo defaultGroupInfo = null;
	private AddrInfo oldDefaultGroupInfo = null;

	private SysStateInfo sysStateInfo = null;

	PowerManager.WakeLock mWakelock = null;

	List<AddrInfo> userList = null;

	private String[] mPermissions = new String[] {
			Manifest.permission.WRITE_EXTERNAL_STORAGE,
	};

	public static boolean mPermissonGrant = true;
	public static boolean mNetworkConnect = false;

	public Product(Context ctx,int productType,int funKey,int iconId,Class cls)
	{
		this.ctx = ctx;
		this.ProductType = productType;
		//this.initLog(ctx);
		this.setLogStatus();
		this.configCenter = new ConfigCenter(ctx,this);
		this.sysConfig = configCenter.getSysConfig();
		this.dbManager = configCenter.getDbOperatorManager();
		this.operator = new ProductOperator(ctx,this.sysConfig,this.dbManager,this,this);
		this.netBroadcast = new NetWorkBroadcast(ctx,this);
		this.batteryBroadcast = new BatteryBroadcast(ctx,this);
		String defaultGroupNum = configCenter.getSysConfig().getDefaultGroupNum();
		this.defaultGroupInfo = GroupInfo.getDefaultUserInfo(defaultGroupNum);
		this.reportAndKeepLive = new ReportAndKeepLive(ctx,operator.lbsOperator,dbManager.getMapDbOperator(),this);

		for(int i = 0; i < ProductConst.Func_Count; i++ )
		{
			int value = CheckData.pow2(i);
			if((funKey & value) != 0)
			{
				IFunc func = creatFunByBit(i);
				funArr[i] = func;
			}
		}

		if(!this.netBroadcast.isConnected())
		{

		}

		this.gCallEventAdapter = new GCallEventAdapter(ctx,this,iconId,cls);
		this.pCallEventAdapter = new PCallEventAdapter(ctx,operator.superCallOperator);
		this.setEventListener(gCallEventAdapter);
		this.setGCallListener(gCallEventAdapter, gCallEventAdapter);

		PowerManager pm = (PowerManager)ctx.getSystemService(ctx.POWER_SERVICE);


		mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.PARTIAL_WAKE_LOCK, "SipProduct");
//			mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "SimpleTimer");
		mWakelock.acquire();
	}

	/** 閺夊啴妾哄Λ锟介弻銉ょ瑢閻㈠疇顕� **/
//	private void checkPermission() {
//		if (Build.VERSION.SDK_INT >= 23) {
//			for (String permission : mPermissions) {
//				if (this.ctx.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
//					mPermissonGrant = false;
//					return;
//				}
//			}
//		}
//		//6.0娑斿澧� 閹达拷 鐎涙ê鍋嶉弶鍐瀹歌尙绮￠懢宄板絿
//		mPermissonGrant = true;
//	}


	private void initLog(Context ctx)
	{
		CrashHandler crashHandler = CrashHandler.getInstance();
		crashHandler.init(ctx);

		Log.initLog();
	}

	private IFunc creatFunByBit(int key)
	{
		Log.d(Log_Key,  "creatFunByBit key = " + key);
		IFunc func = null;
		switch (key) {
			case ProductConst.Func_Sys:
				boolean networkDisconnect = netBroadcast.isConnected();
				Log.d(Log_Key, "creatFunByBit networkDisconnect = " + networkDisconnect);
				SysFunc sysFunc = new SysFunc(ctx,sysConfig,operator.sysOperator,dbManager,this,networkDisconnect);
				sysFunc.setSysListener(this);
//			sysFunc.setLoginListener(this);
//			this.operator.sysOperator.setLoginListener(this);
				func = sysFunc;
				break;
			case ProductConst.Func_Media:
				func = new MediaFunc(ctx);
				break;
			case ProductConst.Func_Addr:
				AddrFunc addrFunc = new AddrFunc(ctx,sysConfig,this,operator.addrPriOperator,dbManager.getAddrDbOperator());
				func = addrFunc;
				break;
			case ProductConst.Func_Call:
				func = new CallFunc(ctx,operator.callTracker,dbManager.getHistoryDbOperator());
//			groupCallFunc.setSpeakListener(this);
//			func = groupCallFunc;
				break;
//		case ProductConst.Func_PrivacyCall:
//			McIdInfo mcInfo = sysConfig.getMcpttLoginInfo().getMcIdInfo();
//			func = new PrivacyCallFunc(ctx,operator.callOperator,dbManager.getAddressDbOperator(),mcInfo);
//			break;
			case ProductConst.Func_Msg:
				func = new MsgFunc(ctx,dbManager.getHistoryDbOperator(),dbManager.getMapDbOperator(),operator.msgOperator);
				break;
			case ProductConst.Func_Local:
				func = new LBSFunc(ctx,configCenter.getLocationConfig(),dbManager.getMapDbOperator());
				break;
			case ProductConst.Func_VoiceReport:
				String lanType = this.sysConfig.getCurLan();
				func = new VoiceReportFunc(ctx,operator,lanType);
				break;
			case ProductConst.Func_BT:
				break;
			default:
				break;
		}
		return func;
	}

	public void setNetworkListener(NetworkListener networkListener)
	{
		this.networkListener = networkListener;
	}
	public void setBatteryistener(Batteryistener batteryistener) {
		this.batteryistener = batteryistener;
	}
	public void setUpdateListener(UpdateListener updateListener) {
		this.updateListener = updateListener;
	}

//	public void setLoginListener(LoginListener loginListener) 
//	{
//		this.loginListener = loginListener;
//	}

	public void setSysListener(SysListener sysListener)
	{
		Log.d(Log_Key,  "setSysListener sysListener = " + sysListener);
		this.sysListener = sysListener;
	}



	//	@Override
//	public void onUpdateAddrList() {
//		// TODO Auto-generated method stub
//		Log.d(Log_Key,  "onUpdateAddrList");
//		Log.d(Log_Key,  "onUpdateAddrList defaultGroupInfo = " + defaultGroupInfo);
//		Log.d(Log_Key,  "onUpdateAddrList curGroupInfo = " + curGroupInfo);
////		if(this.defaultGroupInfo == null)
//		{
//			List<GroupInfo> userList = operator.addrOperator.getGroupList();
//			if(userList != null
//					&& userList.size() > 0)
//			{
//				for(Iterator<GroupInfo> itor = userList.iterator();itor.hasNext();)
//				{
//					GroupInfo info = itor.next();
//					if(info.getType() == GroupInfo.GroupType_Default)
//					{
//						this.setDefaultGroupInfo(info);
//					}
//				}
//			}
//		}
//		if(sysAddrListener != null)
//		{
//			sysAddrListener.onUpdateAddrList();
//		}
//	}
	public void loadAddress()
	{
		AddrFunc func = (AddrFunc)funArr[ProductConst.Func_Addr];
		if(func != null)
		{
			func.loadAddress();
		}
	}
	public void setAddrListener(AddrListener listener)
	{
		IFunc func = funArr[ProductConst.Func_Addr];
		if(func != null)
		{
			AddrFunc sysFun = (AddrFunc)func;
			sysFun.setListener(listener);
		}
	}
	public void setNewGroupListener(NotifyNewGroupListener newGroupListener)
	{
		IFunc func = funArr[ProductConst.Func_Addr];
		if(func != null)
		{
			AddrFunc sysFun = (AddrFunc)func;
			sysFun.setNewGroupListener(newGroupListener);
		}
	}
	public void setSysMsgListener(SysMsgListener sysMsgListener)
	{
		IFunc func = funArr[ProductConst.Func_Sys];
		if(func != null)
		{
			SysFunc sysFun = (SysFunc)func;
			sysFun.setSysMsgListener(sysMsgListener);
		}
	}

	public void setEventListener(EventListener listener)
	{
		IFunc func = funArr[ProductConst.Func_Media];
		if(func != null)
		{
			MediaFunc mediaFun = (MediaFunc)func;
			mediaFun.setListener(listener);
		}
	}

	public void setSingleCallListener(CallListener callListener)
	{
		IFunc func = funArr[ProductConst.Func_Call];
		if(func != null)
		{
			CallFunc callFun = (CallFunc)func;
			callFun.setSingleCallListener(callListener);
		}
	}

	public void setHalfCallListener(CallListener listener,GroupCallSpeakListener floorListener)
	{
		if(this.gCallEventAdapter != null)
		{
			gCallEventAdapter.setHalfCallListener(listener, floorListener);
		}
	}


	private void setGCallListener(CallListener listener,GroupCallSpeakListener floorListener)
	{
		IFunc func = funArr[ProductConst.Func_Call];
		if(func != null)
		{
			CallFunc groupCallFun = (CallFunc)func;
			groupCallFun.setGCallListener(listener,floorListener);
		}
	}

	public void setPCallClass(Class cls)
	{
		IFunc func = funArr[ProductConst.Func_Call];
		if(func != null)
		{
			CallFunc callFun = (CallFunc)func;
			callFun.setPCallClass(cls);
		}
	}

	public void setMsgListener(MsgListener listener)
	{
		IFunc func = funArr[ProductConst.Func_Msg];
		if(func != null)
		{
			MsgFunc msgFun = (MsgFunc)func;
			msgFun.setMsgListener(listener);
		}
	}

	public void setNotifyListener(NotifyListener listener)
	{
		IFunc func = funArr[ProductConst.Func_Msg];
		if(func != null)
		{
			MsgFunc msgFun = (MsgFunc)func;
			msgFun.setNotifyListener(listener);
		}
	}
	public void setAppLogListener(AppLogListener appLogListener) {
		Log.d(Log_Key, "setAppLogListener setAppLogListener = " + appLogListener);
		IFunc func = funArr[ProductConst.Func_Msg];
		if(func != null)
		{
			MsgFunc msgFun = (MsgFunc)func;
			msgFun.setAppLogListener(appLogListener);
		}
	}

//	public void setLbsListener(LbsListener listener) 
//	{
//		reportAndKeepLive.setListener(listener);
//	}

	public SipOperator getOperator(int funType)
	{
		SipOperator sipOperator = null;
		if(funType == ProductConst.Func_SysMsg)
		{
			sipOperator = operator.sysMsgOperator;
			return sipOperator;
		}

		IFunc func = funArr[funType];
		if(func == null)
		{
			String errStr = Resource.getString("permission_err");//ctx.getString(R.string.permission_err);
			CommDlg.showToast(ctx,errStr);
			return null;
		}
		switch (funType) {
			case ProductConst.Func_Sys:
				sipOperator = operator.sysOperator;
				break;
			case ProductConst.Func_Addr:
				sipOperator = operator.addrOperator;
				break;
			//		case PuoductConst.Func_GroupCall:
			//			sipOperator = operator.addrOperator;
			//			break;
			case ProductConst.Func_Call:
				sipOperator = operator.callOperator;
				break;
			case ProductConst.Func_Msg:
				sipOperator = operator.msgOperator;
				break;
			case ProductConst.Func_Local:
				sipOperator = operator.lbsOperator;
				break;
//						case ProductConst.Func_VoiceReport:
			//			sipOperator = operator.vrOperator;
			default:
				String errStr = Resource.getString("permission_err");//ctx.getString(R.string.permission_err);
				CommDlg.showToast(ctx,errStr);
		}
		return sipOperator;
	}

	public ISuperCallOperator getSuperCallOperator()
	{
		return operator.superCallOperator;
	}

	public ISysOperator getSysOperator()
	{
		IFunc func = funArr[ProductConst.Func_Sys];
		if(func != null)
		{
			SysFunc sysFun = (SysFunc)func;
			return sysFun.getSysOperator();
		}
		return null;
	}

	public AddrInfo getUserInfoByNum(String num)
	{
		Log.d(Log_Key, "getUserInfoByNum num = " + num);
		if(num == null
				|| num.length() <= 0)
		{
			return null;
		}
//		if(userList == null
//				|| userList.size() <= 0)
//		{
		userList = operator.addrOperator.getUserAddrList();
//		}
		Log.d(Log_Key, "getUserInfoByNum userList = " + userList);
		if(userList != null
				&& userList.size() > 0)
		{
			for(Iterator<AddrInfo> itor = userList.iterator();itor.hasNext();)
			{
				AddrInfo info = itor.next();
				String id = info.getMcId();
				if(num.equals(id))
				{
					return info;
				}
			}
		}
		return new UserInfo(num);
	}

	public AddrInfo getUserInfoByNum(String gNum,String num)
	{
		Log.d(Log_Key, "getUserInfoByNum gNum = " + gNum + " num = " + num);
		if(num == null
				|| num.length() <= 0)
		{
			return null;
		}
		if(gNum == null
				|| gNum.length() <= 0)
		{
			return null;
		}
//		if(userList == null
//				|| userList.size() <= 0)
//		{
		userList = operator.addrOperator.getUserAddrList(gNum);
//		}
		Log.d(Log_Key, "getUserInfoByNum userList = " + userList);
		if(userList != null
				&& userList.size() > 0)
		{
			for(Iterator<AddrInfo> itor = userList.iterator();itor.hasNext();)
			{
				AddrInfo info = itor.next();
				String id = info.getMcId();
				if(num.equals(id))
				{
					return info;
				}
			}
		}
		return new UserInfo(num);
	}

	public GroupInfo getGroupInfoByNum(String num)
	{
		if(num == null
				|| num.length() <= 0)
		{
			return null;
		}
		List<GroupInfo> userList = operator.addrOperator.getGroupList();
		Log.d(Log_Key, "getGroupInfoByNum userList = " + userList);
		if(userList != null
				&& userList.size() > 0)
		{
			for(Iterator<GroupInfo> itor = userList.iterator();itor.hasNext();)
			{
				GroupInfo info = itor.next();
				if(info != null
						&& info.isSameOne(num))
				{
					return info;
				}
			}
		}
		return new GroupInfo(GroupInfo.GroupType_Incomplete,num,num,GroupInfo.Group_Id_Root,0, CallTimer.T180_DEFAULT,0);
	}


	public List<String> getGroupIDList()
	{
		List<String> idList = new Vector<String>();
		List<GroupInfo> userList = operator.addrOperator.getGroupList();
		Log.d(Log_Key, "getGroupInfoByNum userList = " + userList);
		if(userList != null
				&& userList.size() > 0)
		{
			for(Iterator<GroupInfo> itor = userList.iterator();itor.hasNext();)
			{
				GroupInfo info = itor.next();
				if(info != null)
					idList.add(info.getMcId());
			}
		}
		return idList;
	}

	public SysConfig getSysConfig() {
		return sysConfig;
	}
	public LocationConfig getLocationConfig()
	{
		return configCenter.getLocationConfig();
	}
	public McpttLoginInfo getMcpttLoginInfo()
	{
		return sysConfig.getMcpttLoginInfo();
	}
	public int getBatteryValue()
	{
		return batteryBroadcast.getBatterValue();
	}

	public void setCurGroupInfo(AddrInfo newGroupInfo)
	{
		Log.d(Log_Key, "setCurGroupInfo curGroupInfo is " + newGroupInfo);
		this.curGroupInfo = newGroupInfo;
		if(newGroupInfo != null)
		{
			String callKey = newGroupInfo.getMcId();
			Log.d(Log_Key, "setCurGroupInfo callKey is " + callKey);
			this.gCallEventAdapter.setCurCallKey(callKey);
		}
	}

	public String getCurGroupCallKey()
	{
		Log.d(Log_Key, "getCurGroupInfo curGroupInfo = " + curGroupInfo);
		if(curGroupInfo == null)
		{
			return defaultGroupInfo.getMcId();
		}
		return curGroupInfo.getMcId();
	}

	public void setCurGroupId(String grpId)
	{
		Log.d(Log_Key, "setCurGroupInfo grpId = " + grpId);
		GroupInfo info = getGroupInfoByNum(grpId);
		Log.d(Log_Key, "setCurGroupInfo info = " + info);
		if(info != null)
		{
			curGroupInfo = info;
			String callKey = info.getGroupNum();
			Log.d(Log_Key, "setCurGroupInfo callKey is " + callKey);
			this.gCallEventAdapter.setCurCallKey(callKey);
		}
	}

	public AddrInfo getCurGroupInfo()
	{
		Log.d(Log_Key, "getCurGroupInfo curGroupInfo = " + curGroupInfo + " defaultGroupInfo = " + defaultGroupInfo);
		if(curGroupInfo == null|| curGroupInfo.getLevel() == 1)
		{
			return defaultGroupInfo;
		}
		return curGroupInfo;
	}

	public AddrInfo getSysGroupInfo()
	{
		return GroupInfo.getDefaultUserInfo();
	}

	public boolean checkNetWork()
	{
		Log.d(Log_Key, "checkNetWork");
		if(this.netBroadcast != null)
		{
			return this.netBroadcast.checkNetWork();
		}
		return false;
	}


	public void setDefaultGroupInfo(AddrInfo info)
	{
		Log.d(Log_Key, "setDefaultGroupInfo info is " + info);
		if(info instanceof GroupInfo)
		{
			GroupInfo gInfo = (GroupInfo)info;
			int t180 = gInfo.getgCallTimer();
			CallTimer.getInstance().updateT180(t180);
		}

		if(info != null)
		{
			this.defaultGroupInfo = info;
			this.sysConfig.setDefaultGroupNum(info.getMcId());

			String allGNum = sysConfig.getAllCallGNum();
			String sosGNum = "";
			if(sysConfig.getSosGroupInfo() != null) {
				sosGNum = sysConfig.getSosGroupInfo().getGroupNum();
			}
			String curGNum = info.getMcId();
			String selfNum = sysConfig.getMcpttLoginInfo().getMcIdInfo().getUserId();
			Log.d(Log_Key,"onAddrUpt allGNum = " + allGNum + " curGNum = " + curGNum+ " selfNum = " + selfNum);
			SysOperator op = (SysOperator)getOperator(ProductConst.Func_Sys);
			op.setCallGNum(allGNum,curGNum,sosGNum,selfNum);

			IFunc func = funArr[ProductConst.Func_Call];
			if(func != null)
			{
				CallFunc callFun = (CallFunc)func;
				callFun.setDefaultGroupInfo(info);
			}

			this.gCallEventAdapter.startRtcpKeepAlive();
//			String curCallKey = info.getMcId();
//			this.gCallEventAdapter.setCurCallKey(curCallKey);
//			String num = info.getMcId();
//			this.operator.sysMsgOperator.sendPublish(num);
			if(defaultGroupListener != null)
			{
				defaultGroupListener.afterSetDefaultGroup();
			}
		}
		else
		{
			this.defaultGroupInfo = GroupInfo.getDefaultUserInfo();
			this.sysConfig.setDefaultGroupNum(GroupInfo.Group_Num_All);
			this.gCallEventAdapter.setCurCallKey(GroupInfo.Group_Num_All);
		}

	}

	public AddrInfo getDefaultGroupInfo()
	{
		Log.d(Log_Key, "getDefaultGroupInfo defaultGroupInfo is " + defaultGroupInfo);
		return this.defaultGroupInfo;
	}

	public void checkCurVersion(Context context,boolean isTip)
	{
		Log.d(Log_Key,  "checkCurVersion isTip = " + isTip);
		//		SysConfig config =  getSysConfig();
		ServerInfo info = SysConfig.getFileServerInfo();
		if(info != null)
		{
			String ipUrl = info.getIp();
			int curVersion = getversionCode();
			UpdateManager manager = new UpdateManager(context,ipUrl,curVersion,isTip,ProductType,this);
			manager.runCheckThread();
		}
	}

	public void beginUpload(Context context,UploadListener listener)
	{
		Log.d(Log_Key,  "beginUpload" );
		//		SysConfig config =  getSysConfig();
		McpttLoginInfo info = sysConfig.getMcpttLoginInfo();
		if(info != null)
		{
			String ip = info.getServerInfo().getIp();
			String num = info.getMcIdInfo().getMcId();
			UploadManager manager = new UploadManager(context,ip,num,listener);
			manager.beginUpload();
		}
	}

	private int getversionCode()
	{
		try
		{
			// 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣鍑ょ礉鐎电懓绨睞ndroidManifest.xml娑撳獘ndroid:versionCode
			String pkName = ctx.getPackageName();
			int versionCode = ctx.getPackageManager().getPackageInfo(pkName, 0).versionCode;
			return versionCode;
		} catch (NameNotFoundException e)
		{
			e.printStackTrace();
			return 0;
		}
	}

	public String getSrvStatusDscp()
	{
		Log.d(Log_Key,  "getSrvStatusDscp");
		return this.operator.getSrvStatusDscp();
	}
	@Override
	public void onLogined(McIdInfo mcIdInfo,ServerInfo info,boolean isLoginSuc)
	{
		Log.d(Log_Key,  "onLogined isLoginSuc = " + isLoginSuc + " isLogined = " + isLogined);
		CrashReport.initCrashReport(ctx.getApplicationContext(),TENCENT_BUGLY_APPID, false);
		CrashReport.setUserId(mcIdInfo.getMcId());
		if(isLoginSuc)
		{
			if (operator != null
					&& !isLogined) {
				int val = sysConfig.getGisInterval();
				reportAndKeepLive.startTimer(val);
				operator.setOnLine(true);
			}
			if(gCallEventAdapter != null)
			{
				if(!isLogined)
				{
					gCallEventAdapter.makeGroupCall();
				}
				gCallEventAdapter.onLogin(isLoginSuc);
			}
			isLogined = true;
		}
		Log.d(Log_Key,  "onLogined mcIdInfo = " + mcIdInfo);
		if(mcIdInfo != null
				&& mcIdInfo.getMcId() != null)
		{
			String id = mcIdInfo.getMcId();
			AddrInfo uInfo =this.getUserInfoByNum(id);
			Log.d(Log_Key,  "onLogined uInfo = " + uInfo);
			if(uInfo != null
					&& uInfo.getName() != null)
			{
				String name = uInfo.getName();
				mcIdInfo.updateName(name);

				Log.d(SysFunc.Log_Key, "ACTION_SIP_RELOGIN this.config.isLogined() = " + this.sysConfig.isLogined());
				this.sysConfig.setUserInfoAfterLoginSuc(name,mcIdInfo.getNum());
			}
		}

		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.onLogined(mcIdInfo,info,isLoginSuc);
			}
		}

	}
	@Override
	public void doNetworkChange(boolean isConn)
	{
		Log.d(Log_Key,  "doNetworkChange isConn = " + isConn);
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.doNetworkChange(isConn);
			}
		}
		if(!isConn) {
			SystemClock.sleep(3000);
//			isLogined = false;
//			this.operator.stop();
		}
	}
	@Override
	public void onLanChange(String lanType) {
		// TODO Auto-generated method stub
		Log.d(Log_Key,  "onLanChange lanType = " + lanType);
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.onLanChange(lanType);
			}
		}
		this.operator.onLanChange(lanType);
	}
	@Override
	public void doForceDetach()
	{
		Log.d(Log_Key,  "doForceDetach");
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.doForceDetach();
			}
		}
		this.getSysConfig().clearUserInfoAfterLogout();
		this.userList = null;
	}
	@Override
	public void doLogout()
	{
		Log.d(Log_Key,  "doLogout");
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.doLogout();
			}
		}
		isLogined = false;
		reportAndKeepLive.stopTimer();
//		defaultGroupInfo = null;
		this.getSysConfig().clearUserInfoAfterLogout();
		this.userList = null;
//		operator.setOperatorStatue(SipOperator.Status_Srv_Start);
	}
	@Override
	public void doExit()
	{
		Log.d(Log_Key,  "doExit");
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.doExit();
				funArr[i] = null;
				func = null;
			}
		}
		netBroadcast.clearResource();
		netBroadcast = null;

		reportAndKeepLive.clearResource();
		reportAndKeepLive = null;

		batteryBroadcast.clearResource();
		batteryBroadcast = null;

		operator.stop();
		operator.clearResource();
		operator= null;

		dbManager.doExit();
		dbManager = null;

		CommDlg.clearToast();

		if(this.gCallEventAdapter != null)
		{
			this.gCallEventAdapter.clearResource();
			this.gCallEventAdapter = null;
		}
		if(this.pCallEventAdapter != null)
		{
			this.pCallEventAdapter.clearResource();
			this.pCallEventAdapter = null;
		}

		if(mWakelock != null)
		{
			mWakelock.release();
		}
//		loginListener = null;
		this.userList = null;
		sysListener = null;
		funArr = null;
		ctx = null;
	}

	@Override
	public void onSysState(SysStateInfo stateInfo) {
		// TODO Auto-generated method stub
		Log.d(Log_Key,  "SysStateInfo stateInfo = " + stateInfo);
		this.sysStateInfo = stateInfo;
		int sysState = stateInfo.getState();
		if(operator != null)
		{
			operator.setOperatorStatue(sysState);
		}
		if(sysListener != null)
		{
			sysListener.onSysState(stateInfo);
		}
		else
		{
			Log.d(Log_Key,  "SysStateInfo sysListener = null");
		}
	}
	@Override
	public void onSipAuthResult(int code)
	{
		Log.d(Log_Key, "onSipAuthResult code = " + code);
		if(code == 404)
		{
			isLogined = false;
		}
		if(sysListener != null)
		{
			sysListener.onSipAuthResult(code);
		}
	}

	//	@Override
//	public void onPublish(int result) {
//		// TODO Auto-generated method stub
//		if(operator != null)
//		{
//			operator.onPublish(result);
//		}
//		if(sysStateInfo != null)
//		{
//			sysStateInfo.setPublishResult(result);
//		}
//		
//		if((result & UserInfo.McType_Ptt) != 0){
//			if((sysConfig != null) && sysConfig.getMcInfo() != null){
//				McIdInfo mcIdInfo = sysConfig.getMcInfo();
//				onLogined(mcIdInfo);
//			}
//		}
//		
//		if(sysListener != null)
//		{
//			sysListener.onPublish(result);
//		}
//	}
	@Override
	public void onForceDetach()
	{
		Log.d(Log_Key,  "forceDetach");
		isLogined = false;
		this.reportAndKeepLive.stopTimer();
		doForceDetach();

		String str = Resource.getString("force_detach");
		CommDlg.showToast(ctx, str);
	}

	public void onSvrRestart()
	{
		Log.d(Log_Key,  "onSvrRestart");
//		this.networkChange(true);
		isLogined = false;
		this.reportAndKeepLive.stopTimer();
		if(operator != null)
		{
			operator.setOnLine(false);
//			operator.restart();
		}
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.doNetworkChange(false);
			}
		}
		if(operator != null)
		{
//			operator.setOnLine(false);
			operator.restart();
		}
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.doNetworkChange(true);
			}
		}

		String str = Resource.getString("svr_restart");
		CommDlg.showToast(ctx, str);
	}

	@Override
	public void onKeepAlive(boolean isconnected) {
		// TODO Auto-generated method stub
		Log.d(Log_Key,  "onKeepAlive isconnected = " + isconnected);
		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
		{
			IFunc func = funArr[i];
			if(func != null)
			{
				func.onKeepAlive(isconnected);
			}
		}
		if(operator != null)
		{
			operator.setOnLine(isconnected);
		}

		if(!isconnected)
		{
			isLogined = false;
			this.reportAndKeepLive.stopTimer();
			String str = Resource.getString("link_disconnect");
			CommDlg.showToast(ctx, str);
		}

		if(sysListener != null)
		{
			sysListener.onKeepAlive(isconnected);
		}
	}

//	@Override
//	public void keepLive(boolean isconnected) 
//	{
//		Log.d(Log_Key,  "keepLive isconnected = " + isconnected);
//		for(int i = ProductConst.Func_Count -1; i >= 0; i-- )
//		{
//			IFunc func = funArr[i];
//			if(func != null)
//			{
//				func.onKeepLive(isconnected);
//			}
//		}
//		if(operator != null)
//		{
//			operator.setOnLine(isconnected);
//		}
//		onKeepLive(isconnected);
//		
//		if(!isconnected)
//		{
//			//this.reportAndKeepLive.stopTimer();
//			String str = Resource.getString("link_disconnect");
//			CommDlg.showToast(ctx, str);
//		}
//	}

	@Override
	public void restartServer() {
		// TODO Auto-generated method stub
		Log.d(Log_Key,  "restartServer");
		if(operator != null)
		{
			operator.restart();
		}
	}
	@Override
	public boolean isLogined()
	{
		return this.isLogined;
	}
	@Override
	public void networkChange(boolean isConnect)
	{
		Log.d(Log_Key,  "networkChange isConnect = " + isConnect);

		mNetworkConnect = isConnect;
		if(operator != null)
		{
			operator.setOnLine(isConnect);
		}

		doNetworkChange(isConnect);
		if(isConnect)
		{
//			operator.startSipService();
			operator.restart();
		}
		if(!isConnect)
		{
			isLogined = false;
			this.reportAndKeepLive.stopTimer();
		}

		if(this.networkListener != null)
		{
			this.networkListener.networkChange(isConnect);
		}
	}

	@Override
	public void BatteryChange(int value) {
		// TODO Auto-generated method stub
		if(batteryistener != null)
		{
			batteryistener.BatteryChange(value);
		}
	}

	@Override
	public void onUpdate(int state) {
		// TODO Auto-generated method stub
		if(UpdateListener.UpdateCancel != state)
		{
			this.operator.setUpdate(true);
		}
		else
		{
			this.operator.setUpdate(false);
		}

		if(this.updateListener != null)
		{
			this.updateListener.onUpdate(state);
		}
	}

	public SysStateInfo getSysStateInfo() {
		return sysStateInfo;
	}

	public String getSysInfoStr()
	{
		StringBuffer strBuf = new StringBuffer("SysInfo:");
		if(sysConfig != null)
		{
			strBuf.append(sysConfig.toStrDesc()).append("\r\n");
		}
		strBuf.append(sysStateInfo.toStrDesc()).append("\r\n");
		if(operator.callTracker != null)
		{
			strBuf.append(operator.callTracker.getSysInfoStr()).append("\r\n");
		}

		return strBuf.toString();
	}

	public void startServer(int funcType){
		switch (funcType) {
			case ProductConst.Func_Sys:
//			sipOperator = operator.sysOperator;
				break;
			case ProductConst.Func_Addr:
//			sipOperator = operator.addrOperator;
				break;
			//		case PuoductConst.Func_GroupCall:
			//			sipOperator = operator.addrOperator;
			//			break;
//		case ProductConst.Func_PrivacyCall:
//			sipOperator = operator.callOperator;
//			break;
			case ProductConst.Func_Msg:
//			sipOperator = operator.msgOperator;
				break;
			case ProductConst.Func_Local:
				LBSFunc func = (LBSFunc)funArr[ProductConst.Func_Local];
				func.startServer();
				break;
			//			case ProductConst.Func_VoiceReport:
			//			sipOperator = operator.vrOperator;
			default:
				String errStr = Resource.getString("permission_err");//ctx.getString(R.string.permission_err);
				CommDlg.showToast(ctx,errStr);
		}
	}

	public void stopServer(int funcType){
		switch (funcType) {
			case ProductConst.Func_Sys:
//			sipOperator = operator.sysOperator;
				break;
			case ProductConst.Func_Addr:
//			sipOperator = operator.addrOperator;
				break;
			//		case PuoductConst.Func_GroupCall:
			//			sipOperator = operator.addrOperator;
			//			break;
//		case ProductConst.Func_PrivacyCall:
//			sipOperator = operator.callOperator;
//			break;
			case ProductConst.Func_Msg:
//			sipOperator = operator.msgOperator;
				break;
			case ProductConst.Func_Local:
				LBSFunc func = (LBSFunc)funArr[ProductConst.Func_Local];
				func.stopServer();
				break;
			//			case ProductConst.Func_VoiceReport:
			//			sipOperator = operator.vrOperator;
			default:
				String errStr = Resource.getString("permission_err");//ctx.getString(R.string.permission_err);
				CommDlg.showToast(ctx,errStr);
		}
	}

	public GCallEventAdapter getGCallEventAdapter() {
		return gCallEventAdapter;
	}
	public PCallEventAdapter getPCallEventAdapter() {
		return pCallEventAdapter;
	}

	//	public static int getTerminalType() {
	//		return terminalType;
	//	}
	public void setLogStatus(){
//		checkPermission();
		if(mPermissonGrant){
			this.initLog(this.ctx);
		}
	}

	@Override
	public ReportData getReportData() {
		// TODO Auto-generated method stub
		ReportData data = ReportData.getDefaultData();
		LBSFunc func = (LBSFunc)funArr[ProductConst.Func_Local];
		if(func != null)
		{
			LocationData locData = func.getCurLocation();
			Log.i(Log_Key, "getReportData locData = " + locData);
			data.setLocData(locData);
		}

//		VitalData vitalData = reportAndKeepLive.getCurVitalData();
//		Log.i(Log_Key, "getReportData vitalData = " + vitalData);
//		data.setVitalData(vitalData);

		int value = batteryBroadcast.getBatterValue();
		data.getVitalData().setBattery(value);

		String callDesc = operator.callTracker.getCallDesc();
		data.getVitalData().setCallDesp(callDesc);

		McIdInfo mcId = this.getMcpttLoginInfo().getMcIdInfo();
		Log.i(Log_Key, "getReportData McpttLoginInfo = " + this.getMcpttLoginInfo());
		String num = mcId.getNum();
		AddrInfo info = this.getUserInfoByNum(num);//.f mcId.getName();
		Log.i(Log_Key, "getReportData info = " + info);
		String name = num;
		if(info != null)
		{
			name = info.getName();
		}
		data.updateMcInfo(num,name);

		return data;
	}

	public static int getProductType() {
		return ProductType;
	}


	public AddrInfo getOldDefaultGroupInfo() {
		return oldDefaultGroupInfo;
	}

	public void setOldDefaultGroupInfo(AddrInfo oldDefaultGroupInfo) {
		this.oldDefaultGroupInfo = oldDefaultGroupInfo;
	}
	public void setDefaultGroupListener(ISetDefaultGroup defaultGroupListener) {
		this.defaultGroupListener = defaultGroupListener;
	}
}
